package compiler;

/**
 * Class that represents a statically recompiled basic block of MIPS code.
 * 
 * In this case, a basic block means all instructions starting at a branch/jump target
 * and ending at the delay slot after the first branch/jump-type instruction reached.
 * 
 * @author Jason
 *
 */
public abstract class BasicBlock {

	/**
	 * Flag set from "likely"-type instructions to skip delay slot.
	 */
	public boolean skipDelaySlot;

	/**
	 * Address (<code>PC</code>) of the first MIPS instruction of this basic block.
	 */
	public int address;

	/**
	 * Used in <code>execute()</code> method implementation to do unsigned operations with the <code>rd</code> register.
	 */
	public long u32_gpr_rd;

	/**
	 * Used in <code>execute()</code> method implementation to do unsigned operations with the <code>rs</code> register.
	 */
	public long u32_gpr_rs;

	/**
	 * Used in <code>execute()</code> method implementation to do unsigned operations with the <code>rt</code> register.
	 */
	public long u32_gpr_rt;

	/**
	 * Used in <code>execute()</code> method implementation to do unsigned operations with the <code>immed</code> value.
	 */
	public long u32_immed;
	
	/**
	 * Used in <code>execute()</code> method implementation for intermediate results of <code>MULT</code>/<code>DIV</code> instructions.
	 */
	public long s64_tmp;
	
	/**
	 * Used to vary the length depending on if delay slots are skipped etc.
	 */
	//public static int instructionLength;
	
	/**
	 * Get a static reference to an instance of this <code>BasicBlock</code> subclass.<br/><br/>
	 * 
	 * If this is not implemented in the subclass (which it should be, because the subclass<br/>
	 * should be programatically generated), it will throw {@link UnsupportedOperationException}.
	 * 
	 * @return a static reference to an instance of this <code>BasicBlock</code> subclass.
	 */
	public static compiler.BasicBlock getBasicBlock() {
		throw new UnsupportedOperationException("Must call getBasicBlock on a concrete subclass of BasicBlock");
	}
	
	/**
	 * Executes this basic block of code.
	 * 
	 * @throws mips.exceptions.MipsException
	 */
	public abstract void execute() throws mips.exceptions.MipsException;
	
	/**
	 * Returns the number of MIPS instructions this basic block contained before translation.
	 * @return
	 */
	public abstract int blockLength();
}

